% $Header: d:/tcc/informan/litprog.nw%v 2.2 1995/01/16 11:19:51 LEEW Exp LEEW $ \documentstyle[noweb,twocolumn]{article} \noweboptions{longchunks,nomargintag,noidentxref,webnumbering} \pagestyle{empty} \let\xnwnotused=\nwnotused \let\nwnotused=\nwoutput \def\nwendcode{\endtrivlist \endgroup \par\noindent} % to avoid extra page breaks \def\RCSdef $#1${\typeout{RCS keyword string: $#1$}\RCS@def#1: {} :.} \def\RCS@def#1: #2 :#3.{\expandafter\def\csname RCS#1\endcsname{#2}} \setlength{\oddsidemargin}{-.5in} \setlength{\evensidemargin}{-.5in} \setlength{\columnsep}{.25in} \setlength{\textwidth}{7.5in} \setlength{\topmargin}{-.5in} \setlength{\textheight}{10in} \setlength{\headheight}{0in} \setlength{\headsep}{0in} \setlength{\parskip}{8pt plus 2pt minus 1.5pt} \setlength{\parindent}{0in} \RCSdef $Date: 1995/01/16 11:19:51 $ \RCSdef $Revision: 2.2 $ \RCSdef $Workfile: litprog.nw $ \RCSdef $Author: LEEW $ \raggedright \def\dos/{{\sc dos}} \def\windows/{Windows} \def\unix/{{\sc unix}} \def\awk/{Awk} \def\web/{{\tt WEB}} \def\noweb/{{\tt noweb}} \def\nuweb/{Nuweb} \def\funnelweb/{FunnelWeb} \def\wordweb/{WinWordWEB} \def\clip/{CLiP} \def\notangle/{{\tt notangle}} \def\noweave/{{\tt noweave}} \def\pal/{PAL} \def\objectpal/{ObjectPAL} \def\basic/{BASIC} \def\paltable/{\verb"easter1.db"} \def\opaltable/{\verb"easter2.db"} \def\menuitem#1{``#1''} \def\aside{\noindent{\bf Aside:} } \def\LL{<{}<}\def\GG{>{}>} \title{Literate Programming in \pal/ and \objectpal/} \author{Lee Wittenberg\thanks{Current address: Computer Science Department, Kean College of New Jersey, Union, NJ 07083.}\\\em Tipton Cole \& Company\\\em 3006 Bee Cave Road, Suite B-200\\\em Austin, TX 78746\\\em (512)~329--0060\\\tt leew@pilot.njin.net} \begin{document} \maketitle \thispagestyle{empty} \section{Introduction} A quiet revolution is taking place in programming circles---a revolution called ``literate programming.'' In 1972, Edsger Dijkstra~\cite{dijkstra-notes} wished for a ``program written down as I can understand it, I want it written down as I would like to explain it to someone.'' Ten years later, Donald Knuth developed the original \web/ system, coining the phrase ``literate programming'' in the process. Literate programming is precisely what Dijkstra wanted: the ability to write a program as you would explain it to another human being, rather than as your compiler would have it. \section{Literate Programming} The literate programming philosophy is that a program needs to be readable by both humans and computers, but these two audiences have quite different needs. Computers need the program to have a fairly rigid syntax, usually with names declared before their use. Human beings, on the other hand, prefer a somewhat looser style, and often like to see how a name is used before worrying about how it is defined. Section headings, cross-references, charts, graphs, footnotes, and the like are similarly helpful to humans, but irrelevant to a computer. The best possible documentation, therefore, will recognize the needs of both audiences. A literate program, commonly called a {\em web}, consists of alternating {\em chunks\/} of descriptive text and code. The chunks are organized for the human reader. Usually, each text chunk describes the following code chunk, and makes full use of appropriate word processing techniques. Each code chunk has a name, which can be used in other code chunks to refer to that particular piece of code. The code chunks can be extracted from the web and placed in order suitable for a compiler (or interpreter). This process is called {\em tangling\/} the web. The process of typesetting the web to produce a human-readable document is called {\em weaving}. \section{Programming with \noweb/} I do all of my \pal/ and \objectpal/ programming using \noweb/~\cite{noweb}, a literate programming tool by Norman Ramsey. A \noweb/ program is a text file, usually with a `{\tt .nw}' extension. Text chunks are introduced by the symbol `\verb"@"' on a line by itself, code chunks by a line containing the chunk's name enclosed in a set of double angle brackets, `{\tt\LL}' and~`{\tt\GG}', followed by an equals sign. Figure~\ref{nw-example} gives an example of an extremely simple \pal/ web. \begin{figure}[htbp]\begin{quote} \tt\raggedright This is a trivial example of a PAL\\ web. It displays a ``hello'' message\\ and then sleeps for a bit\\ before it's done.\\ \LL{}*\GG=\\ MESSAGE "Hello, world!"\\ SLEEP \LL{}An appropriate interval\GG\\ How long is appropriate?\\ Let's say 2000, for now.\\ \LL{}An appropriate interval\GG=\\ 2000\\ \end{quote} \caption{\label{nw-example}A simple \pal/ web.}\end{figure} Note the use of the code chunk {\tt\LL}\verb"An appropriate interval"{\tt\GG} in the definition of {\tt\LL}\verb"*"{\tt\GG}. Tangling in \noweb/ is accomplished with the \notangle/ command. Assuming that the web in Figure~\ref{nw-example} is in the file \verb"example.nw", the \dos/ command $$\mbox{\verb"notangle example.nw > example.sc"}$$ tangles it. The output is redirected to create the file \verb"example.sc". Figure~\ref{sc-example} shows the resulting script. \begin{figure}[htbp] \begin{quote}\begin{verbatim} MESSAGE "Hello, world!" SLEEP 2000 \end{verbatim}\end{quote} \caption{\label{sc-example}The result of tangling Figure~\protect\ref{nw-example}} \end{figure} By default, tangling begins with the~{\tt\LL*\GG} chunk (it is possible to specify a different chunk on the command line). As \notangle/ copies this ``root'' chunk to its output, it replaces each chunk name it encounters with the appropriate definition, so \verb"SLEEP "{\tt\LL}\verb"An appropriate interval"{\tt\GG} becomes \verb"SLEEP 2000" in the output, and the resulting program is pretty much what you would expect. \label{weaving} But the real payoff comes with \notangle/'s companion program, \noweave/, which produces a beautifully formatted version of the web, designed to be read by humans. Figure~\ref{noweave-output} is the result. \begin{figure}[hbtp]\begin{quotation} \nwbegindocs{1} This is a trivial example of a PAL web. It displays a ``hello'' message and then sleeps for a bit before it's done. \nwenddocs{} \nwbegincode{2} \moddef{*~{\footnotesize\rm1}}\endmoddef MESSAGE "Hello, world!" SLEEP \LA{}An appropriate interval~{\footnotesize\rm2}\RA{} \xnwnotused{*} \nwendcode \nwbegindocs{3} How long is appropriate? Let's say 2000, for now. \nwenddocs \nwbegincode{4} \moddef{An appropriate interval~{\footnotesize\rm2}}\endmoddef \nwcodecomment{This code is used in chunk 1.} \nwendcode \end{quotation} \caption{\label{noweave-output}Formatted output from Figure~\protect\ref{nw-example}} \end{figure} The text chunks are formatted in a roman font, with paragraphs properly indented. The code chunks are set in a fixed-width typewriter font, with chunk names in italics (and the~{\tt\LL}\thinspace{\tt\GG} pairs replaced by~\LA\thinspace\RA). The chunks are also {\em cross-referenced\/}: each chunk is numbered, and has a footnote that tells where it is used, if at all. Since this example is so short, there isn't much need for cross-referencing, but this feature is invaluable in a web of any size. \section{\noweb/ in Action} \let\nwnotused=\nwoutput The best way to understand what literate programming is all about is to build a web. This article is actually a web containing two programs: one in \pal/~4.x, the other in \objectpal/. From a single source file, {\tt\RCSWorkfile}, \noweb/ generated a typeset copy of this article, a \pal/ script, and an \objectpal/ method. Since the purpose of this article is to introduce the concept of literate programming, and not to discuss interesting Paradox programming tricks, I have chosen to implement a fairly simple algorithm and to make the \pal/ script and the \objectpal/ method do pretty much the same thing. Both calculate dates of Easter for a given range of years, and create a table---keyed to the year---containing the results. The algorithm is from Knuth~\cite{knuth}. Since expressions and identifiers are pretty much the same in \pal/ and \objectpal/, the same variable names can be used for both implementations. The algorithm-related code chunks accompany the algorithm. \label{same code} \newcounter{step} \begin{list}{\bf Step~\arabic{step}.}% {\usecounter{step}\settowidth{\labelwidth}{\bf Step 10.}% \setlength{\leftmargin}{\labelwidth}\addtolength{\leftmargin}{\labelsep}} \item[] Let $y$ be the year for which the date of Easter is desired. \item Set $g\gets(y\bmod19)+1$. Easter calculations depend on a 19-year cycle. A year's place in this cycle is called its ``golden number.'' <>= golden_number = MOD(easter_year, 19) + 1 @ \par Note that, in place of the single letters $y$ and $g$, I use [[easter_year]] and [[golden_number]] as identifiers, preferring good programming style to mathematical consistency. I use [[easter_year]] instead of [[year]], because the latter is a reserved word in \pal/~4.x. \item Set $c \gets \left\lfloor y/100 \right\rfloor + 1$. This step determines the century in which the year occurs (more or less---this description isn't quite accurate for years that are divisible by 100, but it will do). Note that `$\left\lfloor\,\right\rfloor$' is mathematical notation for the ``floor'' function. <>= century = FLOOR(easter_year/100) + 1 @ \par \item Set $x \gets \left\lfloor 3c/4 \right\rfloor - 12$, and $z \gets \left\lfloor (8c+5)/25 \right\rfloor - 5$. A couple of corrections are necessary due to idiosyncracies in the Gregorian calendar. The former, $x$, calculates the number of years divisible by~4 in which there is no leap year, such as 1900. The latter, $z$, is a special correction designed to keep Easter in step with the moon's orbit. <>= leap_year_correction = FLOOR(3*century/4) - 12 lunar_correction = FLOOR((8*century+5)/25) - 5 @ \par \item Set $d \gets \left\lfloor 5y/4 \right\rfloor - x - 10$. This tricky little formula computes a date that falls on a Sunday. <>= sunday = FLOOR(5*easter_year/4) - leap_year_correction - 10 @ \par \item Set $e \gets (11g+20+z-x) \bmod 30$. If $e = 25$ and the golden number~$g$ is greater than~11, or if $e=24$, increase $e$ by 1. The ``epact,'' $e$, is used to calculate when a full moon occurs. <>= epact = MOD(11*golden_number + 20 + lunar_correction - leap_year_correction, 30) IF (epact = 25 AND golden_number > 11) OR (epact = 24) epact = epact + 1 ENDIF @ \par \item Set $m \gets 44 - e$. If $m < 21$ then set $m \gets m + 30$. Easter is defined as ``the first Sunday following the first full moon which occurs on or after March~21.'' This formula finds the first full moon after March~21. <>= full_moon = 44 - epact IF full_moon < 21 full_moon = full_moon + 30 ENDIF @ \par \item Set $n \gets m + 7 - ((d+m) \bmod 7)$. This formula finds the Sunday immediately after the aforementioned full moon. <>= easter_sunday = full_moon + 7 - MOD(sunday + full_moon, 7) @ \par \item If $n > 31$, the date is $(n-31)$ April; otherwise it is $n$ March. <>= IF easter_sunday > 31 easter_sunday = easter_sunday - 31 easter_month = "April" easter_month = "March" ENDIF \end{list} Putting it all together: <>= <> <> <> <> <> <> <> <> The desired date is contained in the variables [[easter_sunday]], [[easter_month]], and [[easter_year]]. \bigskip\aside Notice that I've been working bottom-up rather than top-down, first coding the algorithm steps, then putting them together when all the steps have been coded. This goes against all received wisdom about good programming practice, but literate programming seems to change some of the rules. The primary focus in a literate program is explaining it to the reader. In a case like this, where the algorithm already exists, it's much more natural to develop a program as I have done, and easier for the reader to understand, as well. However, when I don't have an algorithm already prepared, I tend to write top-down, using the chunks for old-fashioned stepwise refinement, as you shall see in the following. \subsection{A \pal/~4.x Script} \label{pal script} Rather than bother with any input, the \pal/ script builds a table, \paltable/, that contains dates of Easter calculated for the years 1950 through~2000. After creating the table, the program iterates over the years, adding an entry to the table for each year. <>= <> FOR easter_year FROM 1950 TO 2000 <> <> ENDFOR <> The \verb"-R" option tells \notangle/ which code chunk to begin with, so the command $$\mbox{\verb"notangle -REASTER.SC litprog.nw > easter.sc"}$$ extracts the \pal/ script, creating the \verb"EASTER.SC" file. The easiest way to clean up is to issue the [[RESET]] command. It has the disadvantage of removing anything that was on the workspace before the script started, but will do for this simple example. <>= RESET \subsubsection{Creating the table} \label{table structure} The \paltable/ table will have three fields: {\em year}, {\em month}, and {\em day}. {\em Month\/} and {\em day\/} represent the date of Easter for the specified {\em year}, which naturally enough, is the key field. {\em Year\/} and {\em day\/} are both numeric (short numbers will do), while {\em month\/} is alphanumeric (5~characters will suffice as Easter occurs only in March or April). The program has to put the table's image on the workspace and get into Coedit mode before adding entries. Since many table operations require subsidiary variables, which may need initialization, the {\LA{}Any other initializations needed for \paltable/\RA} chunk is useful for writing initialization code wherever in the web is most appropriate, yet insuring that the initialization is performed immediately after the table is created. <>= CREATE "easter1" "Year" : "S*", "Month" : "A5", "Day" : "S" <> COEDIT "easter1" \subsubsection{Adding an Easter date to the table} [[APPENDARRAY]] appears to be the simplest technique \pal/~4.x provides for adding records to a table. <>= newdate[2] = easter_year newdate[3] = easter_month newdate[4] = easter_sunday APPENDARRAY newdate Unlike simple variables, the [[newdate]] array must be declared before it is used. Its first element refers to the \paltable/ table. <>= ARRAY newdate[4] newdate[1] = "easter1" @ %def newdate \subsubsection{A minor problem} Unfortunately, \pal/~4.x does not provide a [[FLOOR]] function, although \objectpal/ does. Since the Easter algorithm never passes a negative number to [[FLOOR]], the [[INT]] function provides a cheap substitute. <>= PROC FLOOR(n) RETURN INT(n) ENDPROC @ %def FLOOR \aside Notice the $\mathord{+}\mathord{\equiv}$ in this chunk definition. \noweave/ uses this to indicate that the chunk has already been defined, and that the code in this definition will be concatenated with the code from previous definitions when the web is tangled. \subsubsection{\pal/ wrapup} The \pal/ script is now complete. Although simple, it demonstrates the literate programming style quite well. Each piece of the script is small and easy to understand. Each non-trivial part of the program is relegated to a chunk, whose name is usually a complete sentence. Since chunk names are typographically distinct from the actual code, they are much easier to read than procedure names would be. In addition, {\em there is no run-time overhead involved in using chunks}, as there would be if I had used procedures for refinements. Each chunk is accompanied by a complete description of what the chunk does, including explanations of {\em why\/} things were (or weren't) done in a particular way. Observations that would be intrusive in standard program comments fit quite well in these descriptions. {\em The program is organized for the human reader, not the compiler}. \subsection{An \objectpal/ Method} \noweb/ is language-independent; it doesn't care whether you are programming in \pal/, \objectpal/, or even Pascal or~C. \notangle/'s \verb"-R" option makes it possible to include programs written in several different languages in a single web.\footnote{This is particularly useful when a program is to be invoked by one or more batch files. The batch files can be in the same web as the program they invoke, and can be easily updated whenever necessary due to program changes.} As I mentioned earlier (Section~\ref{same code}), with a little bit of care, it is possible to share code between \pal/ and \objectpal/ applications. If it is necessary to maintain both a \dos/ and \windows/ version of a program, putting them in the same web will help keep them ``in sync,'' making it much less likely that any changes will render the two versions incompatible. A useful technique in \objectpal/ is to write a program as a [[pushButton]] method, linking its execution to a button on some form. I create such a method here, assuming that it will be attached to a button labelled ``Generate Easter Table'' on some form. I use the \verb".txt" extension for \objectpal/ files, because that's what the Paradox for Windows \menuitem{\underline{E}dit$|$Paste Fro\underline{m} File} menu item seems to prefer. <>= METHOD pushButton(VAR eventInfo Event) <> ENDVAR <> ENDMETHOD @ %def pushButton eventInfo In \objectpal/, all variables have to be declared. If the web didn't also contain a \pal/~4.x script, I would have declared these variables as they made their appearence in the algorithm. Since I didn't do it then, I'd better do it now. The variables are declared to be of type [[Number]] (except for [[easter_month]], which is a [[String]]), rather than [[SmallInt]] or [[LongInt]], because for some inexplicable reason, \objectpal/ gets upset\footnote{At least it used to; I don't know about~5.0.} when one tries to assign the result of [[FLOOR]] to an integer variable (even though the result {\em must\/} be integral). <>= easter_year Number easter_month String easter_sunday Number golden_number Number century Number leap_year_correction Number lunar_correction Number sunday Number epact Number full_moon Number @ %def easter_year easter_month easter_sunday golden_number century @ %def leap_year_correction lunar_correction sunday epact full_moon Since the form can take care of all necessary input, [[FirstYear]] and [[LastYear]] will control the [[FOR]] loop, rather than the ``hard-coded'' years 1950 and~2000, and I assume that the form will contain Field objects with these names. Alternatively, it may provide them as global variables that are initialized somehow before [[pushButton]] is invoked, or as symbolic constants. In any event, this is the form's responsibility. \label{o-pal variables} Not surprisingly, the control flow is similar to that of the \pal/ script. <>= <> FOR easter_year FROM FirstYear TO LastYear <<\scriptsize\it Give other Windows programs a chance to run>> <> <<\scriptsize\it Give other Windows programs a chance to run>> <> ENDFOR <<\scriptsize\it Give other Windows programs a chance to run>> <> The only surprise here is the \LA\scriptsize\it Give other Windows programs a chance to run\RA\ chunk, which is scattered all over the place. \windows/ is a ``cooperative multitasking'' system, so each application must voluntarily give up control of the CPU from time to time, to let other applications run. Since \objectpal/ doesn't do this automatically, I like to give other programs a chance whenever possible. I use a smaller font for this chunk name so that it's fairly unobtrusive, and doesn't interfere with the program proper. <<\scriptsize\it Give other Windows programs a chance to run>>= sleep() There's no general desktop cleanup necessary yet; I'll add cleanup code as it becomes necessary. \subsubsection{Creating the table} It appears that the only way to create a table in \objectpal/ is to use the [[create]] pseudo-method with a [[Table]] variable. However, only a [[TCursor]] can actually add records to a table. There doesn't seem to be any getting around the fact that two variables are needed for what should be a one variable job. The \opaltable/ table has the same structure as \paltable/, described in Section~\ref{table structure}. <>= dummy = create "easter2.db" with "Year" : "S", "Month" : "A5", "Day" : "S" key "Year" endcreate easter_table.open("easter2.db") easter_table.edit() Since the [[Table]] variable is never used for anything other than the initial creation, ``[[dummy]]'' seems an appropriate name. <>= dummy Table easter_table TCursor @ %def dummy easter_table The [[easter_table]] must be closed when the method ends to make sure the last record added gets posted to the table. <>= easter_table.close() \subsubsection{Adding an Easter date to the table} Adding records to a table in \objectpal/ is straightforward: insert a new record, and assign the appropriate values to the appropriate fields. <>= easter_table.insertRecord() easter_table."Year" = easter_year easter_table."Month" = easter_month easter_table."Day" = easter_sunday @ \nopagebreak % Ugh! \subsubsection{\objectpal/ wrapup} Now that the \objectpal/ method is complete, note that the only differences between it and the \pal/ script of Section~\ref{pal script} are syntactic. \subsection{Version Control Information} Since a \noweb/ program is a text file, version control information can easily be included in the woven output. This information is updated automatically, whenever the program is ``checked in.'' The following is the relevant information for the programs in this article. \begin{list}{}{ \setlength{\labelwidth}{8em} \setlength{\leftmargin}{9em} \setlength{\labelsep}{0em} \setlength{\itemsep}{0in}\setlength{\parsep}{0in} \renewcommand{\makelabel}[1]{\bf #1:\hfil} \item[File]{\tt\RCSWorkfile} \item[Author]\RCSAuthor \item[Revision]\RCSRevision \item[Last Modified]\RCSDate \end{list} \subsection{List of Chunk Names} \noweb/ can automatically generate an index of chunk names used in the web, and the pages on which they are defined and used. References to chunk definitions are underlined. \medskip\nowebchunks \subsection{List of Identifiers} \noweb/ can also keep track of identifier definitions and usage. \medskip\nowebindex \section{Producing Formatted Output} The \noweave/ program, discussed in Section~\ref{weaving}, does not produce its formatted output directly. It produces a file that is then processed by the \TeX \footnote{``Insiders pronounce the $\chi$ of \TeX\ as a Greek chi, not as an `x', so that \TeX\ rhymes with the word blecchhh. It's the `ch' sound in Scottish words like {\sl loch\/} or German words like {\sl ach\/}; it's a Spanish `j' and a Russian `kh'. When you say it correctly to your computer, the terminal may become slightly moist.''~\cite{TeXbook}} typesetting system. \TeX\ is the typesetting system of choice for literate programming systems for a variety of reasons: \begin{enumerate} \item \TeX\ is readily available. Implementations exist for pretty much every computer in existence, and are usually available free of charge. I use the excellent em\TeX\ implementation for \dos/, by Eberhard Mattes, which is freely distributable. \item \TeX\ is portable. It is designed to be as machine-independent as possible. Output generated by em\TeX\ on my PC and that generated by, say, a \unix/ implementation will be {\em identical}. \item \TeX\ is stable. Before a program can be certified ``\TeX,'' it must pass a rigorous test suite called the ``trip test.'' Since \TeX\ is not a commercial product, it is not subject to the whims of a manufacturer. \item The quality of \TeX\ output is significantly better than that of any commercial word processor or desktop publisher on the market today. \end{enumerate} \noindent On the other hand, there is no reason a literate programming system {\em has\/} to use \TeX. A number of non-\TeX\ systems exist, and many are suitable for programming in \pal/ and \objectpal/ (see Section~\ref{LP systems}). \section{Availability} \label{LP systems} Although it is not in the public domain, \noweb/ is freely distributable---this article (and the programs it generates) were created using the \dos/ implementation. Other literate programming systems suitable for \pal/ and \objectpal/ are also available. \funnelweb/ and \nuweb/ are \TeX-based; \clip/ can be used with any word processor; and \wordweb/ is a collection of macros that provide a simple literate programming environment in Word for Windows. All of these systems are freely distributable. If you would like to find out more about literate programming, I recommend that you subscribe to the ``LitProg'' discussion group on the Internet. All discussion is via electronic mail, so it should be possible to subscribe from CompuServe, or any other service that can send and receive Internet mail. To subscribe, send a message to \verb"LitProg-Request@SHSU.edu"\footnote{CompuServe users should prepend ``\verb">INTERNET:"'' to this ad\-dress.}, and include $$\hbox{\verb'SUBSCRIBE LitProg "your name"'}$$ in the body of the message. As the official welcoming notice says, ``Novices are welcome; it is intended that this group should be a place where newcomers can be welcomed into the fold as well as a place where seasoned literate programmers can discuss fine points of technique.'' \section{Discussion} In the introduction, I stated that literate programming is revolutionary. It is not ``the only game in town,'' though. The ``visual programming'' revolution is also gaining ground. Although visual programming is receiving the lion's share of publicity, I believe that literate programming is much more significant for the professional programmer. Visual programming, like \basic/ before it, is designed for the neophyte. Writing a program is easier than ever before. However, just as \basic/'s [[GOTO]] statement led to ``spaghetti code'' that was impossible to maintain, visual programming systems create their own maintenance problems. In Paradox for Windows, for example, the connections between objects are invisible, creating the potential for spaghetti of another kind. Objects can refer to other objects in many ways, and there is no way---short of examining every object---to determine whether a non-local identifier (e.g. [[FirstYear]] and [[LastYear]] in Section~\ref{o-pal variables}) is a variable, constant, or graphical object, and where in the ``container hierarchy'' it resides. Maintaining such a system can become a nightmare. Literate programming, on the other hand, is not for the beginner. The literate programmer must be proficient in at least two languages: a programming language, like \pal/ or \objectpal/, and a text formatting language, like \TeX\ or a commercial word processor. Since the bulk of a web is explanation, rather than code, the programmer has to take the time to think through the program in order to be able to explain it. As in any programming methodology, time spent in thought ``up front'' translates into reduced debugging and easier maintenance. What literate programming adds to the mix is that the programmer's thoughts no longer disappear into thin air once the program is written; they are preserved in the web. The programmer who maintains the web has these thoughts as a foundation for future work. For the professional programmer, {\em maintenance is everything}. A literate program is a maintainable program. But, above all, literate programming is {\em fun}. The tedium of rearranging bits of code to cater to a compiler is gone. In its place is a process of discovery. As you write your explanations, the code unfolds naturally, as if it had always been there and you just now happened to find it. The phenomenon of ``code that seems to write itself'' is common among literate programmers, as is the practice of passing programs around for comments---and actually getting them! I could go on and on. Literate programming techniques free the programmer to focus on the uniquely human aspects of programming, leaving the computer to perform the more mundane tasks. The benefits are there for the taking. Take them. \bibliographystyle{plain} \bibliography{litprog} \end{document} % $Log: litprog.nw%v $ %Revision 2.2 1995/01/16 11:19:51 LEEW %Finally modified PVCS keywords to RCS keywords (long overdue) %Revision 2.1 1995/01/15 17:29:01 LEEW %Final cleanup; ready for submission. %Revision 2.0 1995/01/15 16:40:22 LEEW %Completed 2nd section; fixed ugly page breaks; general cleanup. %Ready for submission to the Informant? %Revision 1.6 1995/01/10 15:00:58 LEEW %Rephrasing & polishing the text. %Revision 1.5 1995/01/08 19:47:18 LEEW %Matched Informant page format as much as possible. %Revision 1.4 1995/01/08 19:25:55 LEEW %updated for new noweb (hopefully) % Revision 1.3 1995/01/08 19:06:18 LEEW % *** empty log message *** % Revision 1.1 1995/01/08 19:03:12 LEEW % Initial revision % Rev 1.4 16 Jan 1994 15:16:24 LEEW % Modified for new noweb. PVCS changes made by hand(!). % Rev 1.3 15 Jun 1993 09:57:52 LEEW % Minor, cosmetic changes. Article ready for submission. % Rev 1.2 14 Jun 1993 09:51:22 LEEW % Added Dennis' suggestions % Rev 1.1 10 Jun 1993 10:29:14 LEEW % Added CRG suggestions. % Rev 1.0 09 Jun 1993 11:38:56 LEEW % Last paragraph finished. Minor cosmetic changes. % First version released for comments. % Rev 0.10 08 Jun 1993 17:34:12 LEEW % Article complete (except for last few sentences). % Rev 0.9 07 Jun 1993 18:11:32 LEEW % Cosmetic work. Added to conclusion. % Rev 0.8 04 Jun 1993 18:08:02 LEEW % ObjectPAL method now working, as well. % Rev 0.7 04 Jun 1993 15:46:12 LEEW % PAL 4.0 example works (results not yet completely checked, however). % Rev 0.6 03 Jun 1993 17:36:56 LEEW % General cleanup work. Through for the day. % Rev 0.5 03 Jun 1993 16:47:08 LEEW % Finished section 2. % Rev 0.4 03 Jun 1993 12:12:32 LEEW % worked on section 2. Started example. % Rev 0.3 02 Jun 1993 17:29:50 LEEW % Added Easter algorithm (and corresponding code chunks). % Rev 0.2 02 Jun 1993 13:04:54 LEEW % Minor changes. Added overall structure. % Rev 0.1 26 May 1993 16:43:48 LEEW % Started writing. Just a few bits and pieces so far. % Rev 0.0 26 May 1993 15:01:14 LEEW % Initial revision. % $Header: d:/tcc/informan/litprog.nw%v 2.2 1995/01/16 11:19:51 LEEW Exp LEEW $